package com.bianyuanren.v4.service.member.impl;

import com.alibaba.fastjson.JSON;
import com.bianyuanren.common.core.controller.BaseController;
import com.bianyuanren.common.core.domain.AjaxResult;
import com.bianyuanren.common.core.text.Convert;
import com.bianyuanren.common.enums.FileSource;
import com.bianyuanren.common.utils.DateUtils;
import com.bianyuanren.common.utils.ServletUtils;
import com.bianyuanren.common.utils.ShareCodeUtil;
import com.bianyuanren.common.utils.StringUtils;
import com.bianyuanren.framework.shiro.service.SysPasswordService;
import com.bianyuanren.framework.util.JwtUtil;
import com.bianyuanren.framework.util.ShiroUtils;
import com.bianyuanren.framework.util.common.Constant;
import com.bianyuanren.v4.service.like.IPpUserFocusService;
import com.bianyuanren.v4.service.member.IPpMemberService;
import com.bianyuanren.v4.service.slide.IPpSlideNumberService;
import com.bianyuanren.v4.mapper.balcklist.PpUserBlacklistMapper;
import com.bianyuanren.v4.mapper.files.PpFilesMapper;
import com.bianyuanren.v4.mapper.invite.PpInviteMapper;
import com.bianyuanren.v4.mapper.like.PpUserFocusMapper;
import com.bianyuanren.v4.mapper.member.PpLoginMapper;
import com.bianyuanren.v4.mapper.member.PpMemberMapper;
import com.bianyuanren.v4.mapper.slide.PpSlideNumberMapper;
import com.bianyuanren.v4.mapper.sysset.SysSetMapper;
import com.bianyuanren.v4.mapper.viporder.PpVipOrderMapper;
import com.bianyuanren.v4.pojo.balcklist.PpUserBlacklist;
import com.bianyuanren.v4.pojo.files.PpFiles;
import com.bianyuanren.v4.pojo.login.PpLogin;
import com.bianyuanren.v4.pojo.member.PpMember;
import com.bianyuanren.v4.pojo.member.PpmemberDto;
import com.bianyuanren.v4.pojo.slide.PpSlideNumber;
import com.bianyuanren.v4.pojo.slide.SildeDay;
import com.bianyuanren.v4.pojo.sysset.SysSet;
import com.bianyuanren.v4.pojo.viporder.PpVipOrder;
import com.bianyuanren.v4.utils.*;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static com.bianyuanren.common.core.domain.AjaxResult.*;

/**
 * 用户扩展Service业务层处理
 *
 * @author ruoyi
 * @date 2019-12-10
 */
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Service
@Slf4j
public class PpMemberServiceImpl implements IPpMemberService {

    @Autowired
    private PpMemberMapper ppMemberMapper;

    @Autowired
    private SysSetMapper sysSetMapper;

    @Autowired
    private PpSlideNumberMapper ppSlideNumberMapper;

    @Autowired
    private PpInviteMapper ppInviteMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysPasswordService sysPasswordService;

    @Autowired
    private PpUserBlacklistMapper blacklistMapper;

    @Autowired
    private PpFilesMapper filesMapper;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private PpVipOrderMapper ppVipOrderMapper;

    @Autowired
    private IPpUserFocusService ppUserFocusService;

    @Autowired
    private PpLoginMapper ppLoginMapper;

    @Autowired
    private PpUserFocusMapper ppUserFocusMapper;

    @Autowired
    private IPpSlideNumberService ppSlideNumberService;

    /**
     * 查询用户扩展
     *
     * @param id 用户扩展ID
     * @return 用户扩展
     */
    @Override
    public PpMember selectPpMemberById(Long id) {
        return ppMemberMapper.selectPpMemberById(id);
    }

    /**
     * 查询用户扩展列表
     *
     * @param ppMember 用户扩展
     * @return 用户扩展
     */
    @Override
    public List<PpMember> selectPpMemberList(PpMember ppMember) {
        List<PpMember> ppMemberList = ppMemberMapper.selectPpMemberList(ppMember);
        ppMemberList.parallelStream().forEach(member -> {
            if (Optional.ofNullable(member.getId()).isPresent()) {
                String key = "pp:member:activetime:" + member.getId();
                if (redisTemplate.hasKey(key)) {
                    Long lastTime = Long.valueOf(redisTemplate.opsForHash().get("pp:member:activetime:" + member.getId(), "lasttime").toString());
                    Long activeTime = (System.currentTimeMillis() - lastTime) / 1000 / 60;
                    if (activeTime < 60) {
                        member.setActiveTime("活跃于" + activeTime + "分钟前");
                    } else {
                        member.setActiveTime("活跃于" + activeTime / 60 + "小时前");
                    }
                }
                member.setFilenumber(filesMapper.selectPpFilesByFileIdAndFileSourceAll(member.getId(), FileSource.PHOTO.getValue()).size());
            }
        });
        return ppMemberList;
    }

    /**
     * 新增用户扩展
     *
     * @param
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertPpMember(String phone, String password, String code, String invitationCode, String identification) {
        System.out.println("邀请码+++++++++++++++++++++++++++++++" + invitationCode);
        PpMember ppMember = new PpMember();
        ppMember.setPhone(phone);
        ppMember.setPassword(password);
        if (StringUtils.isBlank(code)) {
            return error("验证码不能为空");
        }
        //判断手机号是否注册过
      /*  PpLogin login = ppLoginMapper.selectLogin(phone);
        if(login!=null){
            return warn("手机号已注册");
        }*/

        if (ppMemberMapper.selectPpLoginByPhoneExist(ppMember.getPhone()) > 0) {
            return warn("手机号已注册");
        }
        String authCode = Constant.CODE.concat(phone);
        if (!code.equals(authCode)) {
            if (!redisTemplate.hasKey(authCode)) {
                return error("验证码不存在或过期，请重新获取(The code does not exist.)");
            }
            if (!code.equals(redisTemplate.opsForValue().get(authCode).toString())) {
                return error("验证码不正确");
            }
        }
        //密码长度校验
        if (password.length() < 6 || password.length() > 16) {
            return new AjaxResult(505, "密码格式为6到16位", null);
        }

        //判断用户之前是否已经用微信登录过
        /*PpLogin wxLongin = ppLoginMapper.selectWxLongin(phone);
        if (wxLongin!=null){
            //之前用户已经用微信登录过
            PpLogin ppLogin = new PpLogin();
            ppLogin.setLoginPhone(phone);
            ppLogin.setPassword(sysPasswordService.encryptPassword(phone, password, code));
            ppLogin.setSalt(code);
            ppLogin.setMemberId(wxLongin.getMemberId());
            ppLogin.setIdentification(identification);
            ppLogin.setCreateTime(DateUtils.getNowDate());
            int result = ppMemberMapper.insertPpLoginAccount(ppLogin);

            // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
            String currentTimeMillis = String.valueOf(System.currentTimeMillis());
            redisTemplate.opsForValue().set(Constant.PREFIX_SHIRO_REFRESH_TOKEN + ppLogin.getLoginPhone(), currentTimeMillis, JwtUtil.getRefreshTokenExpireTime(), TimeUnit.SECONDS);
            // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
            String token = JwtUtil.sign(ppLogin.getLoginPhone(), currentTimeMillis, "phone", String.valueOf(ppLogin.getMemberId()));
            ServletUtils.getResponse().setHeader("Authorization", token);
            ServletUtils.getResponse().setHeader("Access-Control-Expose-Headers", "Authorization");
            return new AjaxResult(520,"跳到首页",null);
        }*/

        //用户没有注册过第一次使用这个app
        ppMember.setCreateTime(DateUtils.getNowDate());
        ppMember.setInvitationCode(ShareCodeUtil.idToCode(System.currentTimeMillis()));
        ppMemberMapper.insertPpMember(ppMember);
        PpLogin ppLogin = new PpLogin();
        ppLogin.setLoginPhone(ppMember.getPhone());
        ppLogin.setPassword(sysPasswordService.encryptPassword(phone, password, code));
        ppLogin.setSalt(code);
        ppLogin.setMemberId(ppMember.getId());
        ppLogin.setIdentification(identification);
        ppLogin.setCreateTime(DateUtils.getNowDate());
        int result = ppMemberMapper.insertPpLoginAccount(ppLogin);

        //添加滑动次数
        threadPoolTaskExecutor.execute(() -> {
            //添加注册赠送滑动次数
            SysSet sysSet = sysSetMapper.selectId(1);
            PpSlideNumber ppSlideNumber = new PpSlideNumber();
            ppSlideNumber.setUserId(ppMember.getId());
            //滑动数表只记录的是固定滑动次数
            //ppSlideNumber.setMaximumSlideNumber(Long.valueOf(sysSet.getRegisterFreeNum()));
            ppSlideNumber.setSlideInsertTime(DateUtils.getNowDate());
            ppSlideNumberMapper.insertPpSlideNumber(ppSlideNumber);
            //判断是否添加注册码
            if (invitationCode != null) {
                PpMember invitationUser = selectInvitationUser(invitationCode);
                if (invitationUser != null) {
                    //调用方法
                    bindFriend(ppMember.getId(), invitationCode);
                    invitationFriend(invitationCode);
                }
            }
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", Long.valueOf(sysSet.getRegisterFreeNum()));
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "num", 0);
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "date", DateUtils.getDate());
        });
        // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        redisTemplate.opsForValue().set(Constant.PREFIX_SHIRO_REFRESH_TOKEN + ppLogin.getLoginPhone(), currentTimeMillis, JwtUtil.getRefreshTokenExpireTime(), TimeUnit.SECONDS);
        // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
        String token = JwtUtil.sign(ppLogin.getLoginPhone(), currentTimeMillis, "phone", String.valueOf(ppLogin.getMemberId()));

        ServletUtils.getResponse().setHeader("Authorization", token);
        ServletUtils.getResponse().setHeader("Access-Control-Expose-Headers", "Authorization");
        return result > 0 ? success() : error();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertPpMemberForPc(PpMember ppMember) {
        if (ppMemberMapper.selectPpLoginByPhoneExist(ppMember.getPhone()) > 0) {
            return warn("手机号已注册");
        }
        ppMember.setCreateTime(DateUtils.getNowDate());
        ppMember.setInvitationCode(ShareCodeUtil.idToCode(ppMember.getPhone()));
        ppMemberMapper.insertPpMember(ppMember);
        PpLogin ppLogin = new PpLogin();
        ppLogin.setLoginPhone(ppMember.getPhone());
        ppLogin.setPassword(sysPasswordService.encryptPassword(ppMember.getPhone(), ppMember.getPassword(), ppMember.getPhone().substring(3, 9)));
        ppLogin.setSalt(ppMember.getPhone().substring(3, 9));
        ppLogin.setMemberId(ppMember.getId());
        ppLogin.setCreateTime(DateUtils.getNowDate());
        int result = ppMemberMapper.insertPpLoginAccount(ppLogin);
        //添加注册赠送滑动次数
        SysSet sysSet = JSON.parseObject(redisTemplate.opsForValue().get("sysSet").toString(), SysSet.class);
        PpSlideNumber ppSlideNumber = new PpSlideNumber();
        ppSlideNumber.setUserId(ppMember.getId());
        ppSlideNumber.setMaximumSlideNumber(Long.valueOf(sysSet.getRegisterFreeNum()));
        ppSlideNumber.setCreateTime(DateUtils.getNowDate());
        ppSlideNumberMapper.insertPpSlideNumber(ppSlideNumber);
        //判断是否开通vip  如果是后台添加的可能开通了vip
        if (ppMember.getIsvip() == 1) {
            //添加会员开通记录信息
            PpVipOrder ppVipOrder = new PpVipOrder();
            ppVipOrder.setMemberId(ppMember.getId());
            ppVipOrder.setBuyTime(ppMember.getVipOpenTime());
            ppVipOrder.setLoseTime(ppMember.getVipCloseTime());
            ppVipOrder.setCreateTime(DateUtils.getNowDate());
            ppVipOrderMapper.insertPpVipOrder(ppVipOrder);
            //添加注册赠送滑动次数
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", Long.valueOf(sysSet.getRegisterFreeNum()));
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "num", 0);
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "date", DateUtils.getDate());
        }
        return result > 0 ? success() : error();
    }

    /**
     * 修改用户扩展
     *
     * @param ppMember 用户扩展
     * @return 结果
     */
    @Override
    public int updatePpMember(PpMember ppMember) {
        ppMember.setUpdateTime(DateUtils.getNowDate());
        //通过生日判断是什么星座的
        Date birthday = ppMember.getBirthday();
        if (birthday != null) {
            int month = MonthAndDayUtil.getMonth(birthday);
            int day = MonthAndDayUtil.getDay(birthday);
            String constellation = ConstellationUtil.getConstellation(month, day);
            ppMember.setConstellation(constellation);
        }
        return ppMemberMapper.updatePpMember(ppMember);
    }

    /**
     * 删除用户扩展对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deletePpMemberByIds(String ids) {
        return ppMemberMapper.deletePpMemberByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除用户扩展信息
     *
     * @param id 用户扩展ID
     * @return 结果
     */
    @Override
    public int deletePpMemberById(Long id) {
        return ppMemberMapper.deletePpMemberById(id);
    }

    /**
     * 获取用户的二维码
     */
    @Override
    public String invitationCode(Long userId) {

        PpMember ppMember = ppMemberMapper.selectPpMemberById(userId);
        String invitationCode = ppMember.getInvitationCode();
        return invitationCode;
    }


    /**
     * 邀请用户下载
     *
     * @param invitationCode
     */
    @Override
    public void invitationFriend(String invitationCode) {
        //通过邀请码获取用户信息
        Date date = new Date();
        //通过邀请码获取对应的用户信息
        PpMember ppMember = ppMemberMapper.selectInvitationCode(invitationCode);
        //先获取设置系统中的邀请可以获取多少的滑动次数
        SysSet sysSet = sysSetMapper.selectId(1);
        Integer inviteFreeNum = sysSet.getInviteFreeNum();
        //获取邀请用户当前的滑动次数
        PpSlideNumber ppSlideNumber = ppSlideNumberMapper.selectId(ppMember.getId());
        threadPoolTaskExecutor.execute(() -> {
            //获取最大滑动次数
            Integer sum = 0;
            Long maximumSlideNumber = ppSlideNumber.getMaximumSlideNumber();
            if (maximumSlideNumber != null) {
                sum += maximumSlideNumber.intValue() + inviteFreeNum;
            }
            ppSlideNumberMapper.updateSlideNumber(ppMember.getId(), sum.longValue());
        });
    }

    /**
     * 绑定好友 填写邀请码
     *
     * @param invitationCode
     */
    @Override
    public void bindFriend(Long userId, String invitationCode) {
        Date date = new Date();
        //通过邀请码获取用户信息 这个用户是上级用户
        PpMember ppMember = ppMemberMapper.selectInvitationCode(invitationCode);
        //当前用户
        PpMember currentUser = ppMemberMapper.selectPpMemberById(userId);
        //先获取设置系统中的绑定可以获取多少的滑动次数
        SysSet sysSet = sysSetMapper.selectId(1);
        Integer bindingFreeNum = sysSet.getBindingFreeNum();
        //获取用户当前的滑动次数 填写邀请码的用户
        //修改滑动次数
        PpSlideNumber ppSlideNumber = ppSlideNumberMapper.selectId(userId);
        threadPoolTaskExecutor.execute(() -> {
            //获取最大滑动次数
            Integer sum = 0;
            Long maximumSlideNumber = ppSlideNumber.getMaximumSlideNumber();
            if (maximumSlideNumber != null) {
                sum += maximumSlideNumber.intValue() + bindingFreeNum;
            }
            ppSlideNumberMapper.updateSlideNumber(userId, sum.longValue());
        });

        //修改用户的上级用户
        currentUser.setParentId(ppMember.getId());
        ppMemberMapper.updatePpMember(currentUser);
        //添加用户邀请关系对象 pp_invite
        ppInviteMapper.insertId(ppMember.getId(), currentUser.getId());
    }

    /**
     * 邀请码获取对应的人
     *
     * @param invitationCode
     */
    @Override
    public PpMember selectInvitationUser(String invitationCode) {
        //通过邀请码获取对应的用户信息
        PpMember ppMember = ppMemberMapper.selectInvitationCode(invitationCode);
        return ppMember;
    }


    /**
     * 判断用户是否为会员
     *
     * @param userId
     */
    @Override
    public Integer isMember(Long userId) {
        //获取用户id
        PpMember ppMember = ppMemberMapper.selectPpMemberById(userId);
        //获取用户的到期时间
        Date vipCloseTime = ppMember.getVipCloseTime();
        if (vipCloseTime == null) {
            return 0;
        } else {
            //判断用户是否到期 1会员没有到期 0会员到期
            if (DateUtils.getNowDate().compareTo(vipCloseTime) < 1) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    /**
     * 判断用户是否有邀请人
     *
     * @param userid
     */
    @Override
    public PpMember isInviter(Long userid) {
        PpMember ppMember = ppMemberMapper.selectPpMemberById(userid);
        //获取邀请人id
        Long parentId = ppMember.getParentId();
        //判断是否为null
        if (parentId != null) {
            PpMember parent = ppMemberMapper.selectPpMemberById(parentId);
            return parent;
        } else {
            return null;
        }
    }

    /**
     * 余额
     *
     * @param userId
     */
    @Override
    public Integer selectBalance(Long userId) {
        PpMember ppMember = ppMemberMapper.selectPpMemberById(userId);
        Integer balance = ppMember.getBalance();
        if (balance != null) {
            return balance;
        } else {
            return 0;
        }

    }

    /**
     * 用户收益
     *
     * @param userId
     */
    @Override
    public BigDecimal selectEarnings(Long userId) {
        PpMember ppMember = ppMemberMapper.selectPpMemberById(userId);
        BigDecimal earnings = ppMember.getEarnings();
        if (earnings != null) {
            return earnings;
        } else {
            return null;
        }
    }

    /**
     * 获取用户头像
     *
     * @param userId
     */
    @Override
    public PpMember selectUserAndFiles(Long userId) {
        //获取当前的用户信息
        PpMember user = ppMemberMapper.selectPpMemberById(ShiroUtils.getAppUserId());
        if (user.getLatitude()==null){
            user.setLatitude((double) 0);
        }
        if (user.getLongitude()==null){
            user.setLongitude((double) 0);
        }
        PpMember ppMember = ppMemberMapper.selectUserAndFiles(userId,user.getLatitude(),user.getLongitude());
        //判断用户是否开启隐藏活跃时间
        if (ppMember.getIsactive() == false) {
            Long aLong = activeTime(ppMember.getId());
            //给活跃时间
            ppMember.setActiveTime(aLong.toString());
            String activeTime = ActiveTimeUtil.activeTime(aLong);
            ppMember.setActiveTime(activeTime);
            ppMember.setCircleTime(user.getCircleTime());
        }
        return ppMember;
    }

    /**
     * 获取年龄
     */
    @Override
    public Integer userAge(Long userId) {
        PpMember ppMember = ppMemberMapper.selectPpMemberById(userId);
        Date birthday = ppMember.getBirthday();
        int ageByBirth = BirthdayUtil.getAgeByBirth(birthday);
        return ageByBirth;
    }

    @Override
    public PpMember test() {
        PpMember ppMember = ppMemberMapper.selectPpMemberById(ShiroUtils.getAppUserId());
        return ppMember;
    }

    /**
     * 获取首页推荐用户列表
     *
     * @return
     */
    @Override
    public List<PpMember> selectIndexMemberList(PpmemberDto ppmemberDto, PpMember ppMember) {
        System.out.println("userID=" + ShiroUtils.getAppUserId());
        //获取拉黑用户id
        PpUserBlacklist ppUserBlacklist = new PpUserBlacklist();
        ppUserBlacklist.setUserId(ShiroUtils.getAppUserId());
        //黑名单列表
        List<Long> blackIds = blacklistMapper.selectPpUserBlack(ShiroUtils.getAppUserId());
        blackIds.add(ppMember.getId());
        //喜欢过的人不在展示 获取喜欢列表
        List<Long> userFocus = ppUserFocusMapper.likeAll(ShiroUtils.getAppUserId());
        blackIds.addAll(userFocus);
       //从redis中取出今天划过的人
        String key = "user:nolike:slidingOver:" + ShiroUtils.getAppUserId();
        //判断redis中是否有值
         if (redisTemplate.hasKey(key)){
             //获取
             List<Long> range = redisTemplate.opsForList().range(key, 0, -1);
             blackIds.addAll(range);
         }
        System.out.println("123456"+blackIds);
        ppmemberDto.setLatitude(ppMember.getLatitude());
        ppmemberDto.setLongitude(ppMember.getLongitude());
        //分页查询
        BaseController.startPage();
        List<PpMember> ppMembers = ppMemberMapper.selectIndexMemberList(ppmemberDto, blackIds);
        ppMembers.stream().forEach(p -> {
            List<PpFiles> ppFilesList = filesMapper.selectPpFilesByFileIdAndFileSourceAll(p.getId(), FileSource.PHOTO.getValue());
            p.setPpFiles(ppFilesList);
        });
        Collections.shuffle(ppMembers);
        return ppMembers;
    }

    /**
     * 开通会员测试
     *
     * @param userId
     * @param time
     * @param timeTpye
     */
    @Override
    public void dredgeMember(Long userId, Integer time, String timeTpye, String orderNumber) {
        //获取设置信息 开通会员添加滑动次数
        SysSet sysSet = sysSetMapper.selectId(1);
        Integer vipFreeNum = sysSet.getVipFreeNum();

        Date date = new Date();
        PpMember ppMember = ppMemberMapper.selectPpMemberById(userId);
        //获取用户当前滑动次数
        PpSlideNumber ppSlideNumber = ppSlideNumberMapper.selectId(userId);
        //获取用户会员到期时间
        Date vipCloseTime = ppMember.getVipCloseTime();

        //第一次开通会员
        if (vipCloseTime == null) {
            //用户第一次开通会员
            if (redisTemplate.hasKey("pp:member:slide:" + ppMember.getId())) {
                Integer maxNum = (Integer) redisTemplate.opsForHash().get("pp:member:slide:" + ppMember.getId(), "totalNum");
                // redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", maxNum + sysSet.getVipFreeNum());
                redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", sysSet.getVipDayNum());
            }
            //获取时间
            Date expireDate = DateMemberUtils.addDate(date, time, timeTpye);
            ppMember.setIsvip(1);
            ppMember.setVipOpenTime(date);
            ppMember.setVipCloseTime(expireDate);
            ppMemberMapper.updatePpMember(ppMember);
        } else {
            //用户续费
            //判断会员是否到期
            if (vipCloseTime != null && date.compareTo(vipCloseTime) < 1) {
                //会员没有到期 向后延期
                Date expireDate = DateMemberUtils.addDate(vipCloseTime, time, timeTpye);
                //修改信息
                ppMember.setVipCloseTime(expireDate);
                ppMemberMapper.updatePpMember(ppMember);
                //修改滑动次数
                threadPoolTaskExecutor.execute(() -> {
                    //获取最大滑动次数
                    Integer sum = 0;
                    Long maximumSlideNumber = ppSlideNumber.getMaximumSlideNumber();
                    if (maximumSlideNumber != null) {
                        sum += maximumSlideNumber.intValue() + vipFreeNum;
                    }
                    ppSlideNumberMapper.updateSlideNumber(userId, sum.longValue());
                });
            } else {
                redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", sysSet.getVipDayNum());
                //修改滑动次数
                threadPoolTaskExecutor.execute(() -> {
                    //添加最大滑动次数
                    Integer sum = 0;
                    Long maximumSlideNumber = ppSlideNumber.getMaximumSlideNumber();
                    if (maximumSlideNumber == null) {
                        sum = maximumSlideNumber.intValue();
                    } else {
                        sum += maximumSlideNumber.intValue() + vipFreeNum;
                    }
                    ppSlideNumberMapper.updateSlideNumber(userId, sum.longValue());
                });
                //获取时间
                Date expireDate = DateMemberUtils.addDate(date, time, timeTpye);
                ppMember.setIsvip(1);
                ppMember.setVipOpenTime(date);
                ppMember.setVipCloseTime(expireDate);
                ppMemberMapper.updatePpMember(ppMember);
            }
        }
    }


    /**
     * 获取信息
     */
    @Override
    public List<PpMember> selectList() {
        return ppMemberMapper.selectList();
    }

    /**
     * 修改用户扩展
     *
     * @param ppMember 用户扩展
     * @return 结果
     */
    @Override
    public void update(PpMember ppMember) {
        System.out.println(ppMember);
        ppMember.setUpdateTime(new Date());
        ppMemberMapper.updatePpMember(ppMember);
    }

    /**
     * 获取活跃时间
     *
     * @param userId
     */
    @Override
    public Long activeTime(Long userId) {
        Long activeTime = Long.valueOf(0);
        if (Optional.ofNullable(userId).isPresent()) {
            String key = "pp:member:activetime:" + userId;
            if (redisTemplate.hasKey(key)) {
                Long lastTime = Long.valueOf(redisTemplate.opsForHash().get("pp:member:activetime:" + userId, "lasttime").toString());
                activeTime = (System.currentTimeMillis() - lastTime) / 1000 / 60;
            }
        }
        return activeTime;
    }

    /**
     * 获取两人之间的距离
     *
     * @param otherId
     */
    @Override
    public Double distance(Long otherId) {
        PpMember user = ppMemberMapper.selectPpMemberById(ShiroUtils.getAppUserId());
        PpMember other = ppMemberMapper.selectPpMemberById(otherId);
        double distance = LocationUtils.getDistance(user.getLatitude(), user.getLongitude(),
                other.getLatitude(), other.getLongitude());

        double kilometre = distance / 1000;
        return kilometre;
    }

    /**
     * 在线好友
     */
    @Override
    public List<PpMember> onlineFriends() {
        List<PpMember> online = new ArrayList<>();
        //获取当前用户的好友
        List<PpMember> ppMembers = ppUserFocusService.friendList();
        for (PpMember ppMember : ppMembers) {
            //获取活跃时间
            Long aLong = activeTime(ppMember.getId());
            if (aLong == 0) {
                online.add(ppMember);
            }
        }
        return online;

    }

    @Override
    public SildeDay slidingToDay() {
        SildeDay sildeDay = new SildeDay();
        Long appUserId = ShiroUtils.getAppUserId();
        //把redis中的值设置成当天的值
        timingUserSlide(appUserId);
        //今天总滑动次数
        String key = "pp:member:slide:" + appUserId;
        if (redisTemplate.hasKey(key)) {
            //判断
            Integer totalNum = (Integer) redisTemplate.opsForHash().get("pp:member:slide:" + appUserId, "totalNum");
            Integer num = (Integer) redisTemplate.opsForHash().get("pp:member:slide:" + appUserId, "num");
            sildeDay.setCurrentSilde(num);
            sildeDay.setTodaySilde(totalNum);
        }
        //获取用户的固定滑动次数 从redis中获取 今天固定滑动原始数据
        PpSlideNumber redisSlideNumber = ppSlideNumberService.settledSlideNumber();
        String settledslide = "pp:member:settledslide:" + appUserId;
        //从数据库获取最新的固定滑动信息
        PpSlideNumber newestSlideNumber = ppSlideNumberMapper.selectUserById(appUserId);
        if (redisTemplate.hasKey(settledslide)){
            //固定最大滑动
            Integer redisMaximumSlideNumber =(Integer) redisTemplate.opsForHash().get(settledslide, "maximumSlideNumber");
            //固定滑动次数滑动过的
            Integer redisNumber = (Integer) redisTemplate.opsForHash().get(settledslide, "slideNumber");
            //现在可以滑动 redis中的固定滑动可以划的
            Integer redisNum= redisMaximumSlideNumber - redisNumber;
            //数据库中的固定滑动次数滑动过的次数
            Long newestNumber = newestSlideNumber.getSlideNumber();
            //数据库中的最大的固定滑动次数
            Long newestMaximumSlideNumber = newestSlideNumber.getMaximumSlideNumber();
            //今天滑动过固定滑动次数
            Integer todayNumber= newestNumber.intValue()-redisNumber;
            //今天最大固定滑动次数
            Integer MaximumSlideNumber =newestMaximumSlideNumber.intValue() - redisMaximumSlideNumber;
            sildeDay.setCurrentSilde(sildeDay.getCurrentSilde()+todayNumber);
            sildeDay.setTodaySilde(sildeDay.getTodaySilde()+redisNum+MaximumSlideNumber);
        }
        return sildeDay;
    }

    @Override
    public Boolean wxLoginSlide() {
        Long appUserId = ShiroUtils.getAppUserId();
        //查询用户信息
        PpMember ppMember = ppMemberMapper.selectPpMemberById(appUserId);
        //添加注册赠送滑动次数
        SysSet sysSet = JSON.parseObject(redisTemplate.opsForValue().get("sysSet").toString(), SysSet.class);
        PpSlideNumber ppSlideNumber = new PpSlideNumber();
        ppSlideNumber.setUserId(ppMember.getId());
        ppSlideNumber.setMaximumSlideNumber(Long.valueOf(sysSet.getRegisterFreeNum()));
        ppSlideNumber.setCreateTime(DateUtils.getNowDate());
        ppSlideNumberMapper.insertPpSlideNumber(ppSlideNumber);
        //判断是否开通vip  如果是后台添加的可能开通了vip
        if (ppMember.getIsvip() == 1) {
            //添加会员开通记录信息
            PpVipOrder ppVipOrder = new PpVipOrder();
            ppVipOrder.setMemberId(ppMember.getId());
            ppVipOrder.setBuyTime(ppMember.getVipOpenTime());
            ppVipOrder.setLoseTime(ppMember.getVipCloseTime());
            ppVipOrder.setCreateTime(DateUtils.getNowDate());
            ppVipOrderMapper.insertPpVipOrder(ppVipOrder);
            //添加注册赠送滑动次数
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", Long.valueOf(200));
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "num", 0);
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "date", DateUtils.getDate());
        } else {
            //添加注册赠送滑动次数
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", Long.valueOf(sysSet.getRegisterFreeNum()));
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "num", 0);
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "date", DateUtils.getDate());
        }
        return true;
    }

    @Override
    public void updateIsActive() {
        Long appUserId = ShiroUtils.getAppUserId();
        ppMemberMapper.updateIsActive(appUserId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateUserPassword(String phone, String password, String code) {
        if (StringUtils.isBlank(code)) {
            return error("验证码不能为空");
        }
        String authCode = Constant.CODE.concat(phone);
        if (!code.equals("222222")) {
            if (!redisTemplate.hasKey(authCode)) {
                return error("验证码不存在或过期，请重新获取(The code does not exist.)");
            }
            if (!code.equals(redisTemplate.opsForValue().get(authCode).toString())) {
                return error("验证码不正确");
            }
        }
        //通过手机号获取用户
        PpLogin ppLogin = ppLoginMapper.selectLogin(phone);
        if (ppLogin == null) {
            return warn("手机号不存在");
        }
        ppLogin.setPassword(sysPasswordService.encryptPassword(phone, password, code));
        ppLogin.setSalt(code);
        int result = ppLoginMapper.updatePpLogin(ppLogin);
        // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        redisTemplate.opsForValue().set(Constant.PREFIX_SHIRO_REFRESH_TOKEN + ppLogin.getLoginPhone(), currentTimeMillis, JwtUtil.getRefreshTokenExpireTime(), TimeUnit.SECONDS);
        // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
        String token = JwtUtil.sign(ppLogin.getLoginPhone(), currentTimeMillis, "phone", String.valueOf(ppLogin.getMemberId()));
        ServletUtils.getResponse().setHeader("Authorization", token);
        ServletUtils.getResponse().setHeader("Access-Control-Expose-Headers", "Authorization");
        return result > 0 ? success() : error();
    }

    @Override
    public int quitLogin() {
        Long appUserId = ShiroUtils.getAppUserId();
        int i = ppLoginMapper.quitLogin(appUserId);
        return i;
    }

    @Override
    public void memberSlide() {
        System.out.println("进入定时任务");
        //调用需要定时清理的数据 获取所有用户的开通会员时间
        SysSet sysSet = JSON.parseObject(redisTemplate.opsForValue().get("sysSet").toString(), SysSet.class);
        Date date = new Date();
        //只查询开通过会员的用户
        List<PpMember> ppMembers = selectList();
        for (PpMember ppMember : ppMembers) {
            //修改滑动次数
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "totalNum", Long.valueOf(sysSet.getRegisterFreeNum()));
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "num", 0);
            redisTemplate.opsForHash().put("pp:member:slide:" + ppMember.getId(), "date", DateUtils.getDate());
            System.out.println("执行定时任务");
        }
    }


    /**
     * redis中添加今天滑动过的人
     * 用户不喜欢的人
     */
    @Override
    public void slidingOver(Long userId) {
        //获取当前用户信息
        Long appUserId = ShiroUtils.getAppUserId();
        //判断是否存在
        String key = "user:nolike:slidingOver:" + appUserId;
        //判断是否今天滑动过(有不喜欢的用户)
        if (!redisTemplate.hasKey(key)) {
            //判断是否开通过会员 不包含
            redisTemplate.opsForList().leftPush("user:nolike:slidingOver:" + appUserId,userId);
        } else {
            //包含对应的key
            //获取出之前的数据 向已经存在的集合中添加添加集合
            redisTemplate.opsForList().rightPushIfPresent("user:nolike:slidingOver:" + appUserId, userId);
        }
    }

    /**
     * 删除redis中对应的key
     */
    @Override
    public void deleteRedis() {
        Set<String> keys = redisTemplate.keys("user:nolike:slidingOver:*");
        if (keys!=null) {
            redisTemplate.delete(keys);
            System.out.println("成功");
        }
    }

    @Override
    public void slidingScreen() {
        Set<String> keys = redisTemplate.keys("user:nolike:slidingScreen:*");
        if (keys!=null) {
            redisTemplate.delete(keys);
            System.out.println("成功");
        }
    }

    /**
     * 筛选不喜欢
     */
    @Override
    public void slidingScreen(Long userId) {
        //获取当前用户信息
        Long appUserId = ShiroUtils.getAppUserId();
        //判断是否存在
        String key = "user:nolike:slidingScreen:" + appUserId;
        //判断是否今天滑动过(有不喜欢的用户)
        if (!redisTemplate.hasKey(key)) {
            //判断是否开通过会员 不包含
            redisTemplate.opsForList().leftPush("user:nolike:slidingScreen:" + appUserId,userId);
        } else {
            //包含对应的key
            //获取出之前的数据 向已经存在的集合中添加添加集合
            redisTemplate.opsForList().rightPushIfPresent("user:nolike:slidingScreen:" + appUserId, userId);
        }
    }


    /**
     * 通过用户输入的昵称判断是否存在
     * @param nickname 昵称
     * @return
     */
    @Override
    public int selectPpMemberByNickname(String nickname) {
        return ppMemberMapper.selectPpMemberByNickname(nickname);
    }

    /**
     * 每天定时更新用户的滑动次数
     * @param userId 用户id
     */
    @Override
    public void timingUserSlide(Long userId) {
        //redis在key
        String key = "pp:member:slide:" + userId;
        //判断redis是否存在
        if (redisTemplate.hasKey(key)){
            //判断redis中的数据不是当天的数据
            if (!DateUtils.getDate().equals(redisTemplate.opsForHash().get(key, "date"))){
                //从新赋值
                redisTemplate.opsForHash().put(key, "num", 0);
                redisTemplate.opsForHash().put(key, "date", DateUtils.getDate());
            }
        }
    }


    /**
     * 后台开通过会员的用户管理
     * @param ppMember
     * @return
     */
    @Override
    public List<PpMember> selectVipPpMemberList(PpMember ppMember) {
        return ppMemberMapper.selectPpMemberList(ppMember);
    }
}
